package com.arron.DesignMode.prototype.deepclone;

import java.io.*;

/**
 * @Classname DeepPrototype
 * @Date 2020/11/6 12:17
 * @Created by 刘
 */
public class DeepPrototype implements Serializable,Cloneable{


    private String name;
    private  DeepCloneableTarget deepCloneableTarget;

    public DeepPrototype(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public DeepCloneableTarget getDeepCloneableTarget() {
        return deepCloneableTarget;
    }

    public void setDeepCloneableTarget(DeepCloneableTarget deepCloneableTarget) {
        this.deepCloneableTarget = deepCloneableTarget;
    }

    //方式一，深拷贝，缺点：如果对象有多个引用对象，则需要拷贝多份引用对象的实例
    @Override
    protected DeepPrototype clone() throws CloneNotSupportedException {

        //只能克隆简单属性，但不能拷贝对象属性
        DeepPrototype clone = (DeepPrototype) super.clone();

        //拷贝对象属性
        clone.deepCloneableTarget = deepCloneableTarget.clone();

        return clone;
    }

    //方式二，使用序列化和反序列化的方式进行深拷贝，缺点：操作比较复杂，优点：一次到位
    public DeepPrototype deepClone(){

        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;

        try {

            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this); // 将本身序列化为对象流

            //再反序列化回来
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);

            DeepPrototype o = (DeepPrototype) ois.readObject();
            return o;
        }catch (Exception e){
            System.out.println(e.getMessage());

            return null;
        }finally {
            //关闭流
            try {

                bis.close();

                ois.close();
                bos.close();
                oos.close();


            }catch (Exception e){
                System.out.println(e.getMessage());
            }

        }
    }





    @Override
    public String toString() {
        return "DeepPrototype{" +
                "name='" + name + '\'' +
                ", deepCloneableTarget=" + deepCloneableTarget +
                '}';
    }
}
